#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <memory.h>
#include <string.h>
void printMatrix();

void init (void)
{
	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 5.0 };
	GLfloat mat_shininess[] = { 50.0 };
	GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

	glClearColor (0.0, 0.0, 0.0, 0.0);
	glShadeModel (GL_SMOOTH);

	glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess);
	glLightfv (GL_LIGHT0, GL_POSITION, light_position);

	glEnable (GL_LIGHTING);
	glEnable (GL_LIGHT0);
	glEnable (GL_DEPTH_TEST);
}


void display (void)
{
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glutSolidSphere (1.0, 40, 50);
	glFlush ();
}


void reshape (int w, int h)
{
	glViewport (0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode (GL_PROJECTION);
	printMatrix();
	glLoadIdentity ();
	printMatrix();
	if (w <= h)
		glOrtho (-1.5, 1.5, -1.5 * (GLfloat) h / (GLfloat) w,
		1.5 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
	else
		glOrtho (-1.5 * (GLfloat) w / (GLfloat) h,
		1.5 * (GLfloat) w / (GLfloat) h, -1.5, 1.5, -10.0, 10.0);
	glMatrixMode (GL_MODELVIEW);
	printMatrix();
	glLoadIdentity ();
	printMatrix();
}

void moveForward(int x)
{
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  if(x==1)
  glTranslatef(0.5,0.0,0.0);
  else if(x==2)
	  glTranslatef(0.0,0.0,0.0);
  else if(x==3)
	  glTranslatef(-0.5,0.0,0.0);
  glutSolidSphere (1.0, 40, 50);
  glFlush ();
  glPopMatrix();
  
}

void printMatrix()
{
	GLdouble projMatrix[16];
	GLdouble modelMatrix[16];
	memset(projMatrix,0,16*sizeof(GLdouble));
	memset(modelMatrix,0,16*sizeof(GLdouble));
	int i,j;
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);

	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("%lf  ",projMatrix[4*i+j]);
		}
		printf("\n");
	}
	printf("========================================\n");
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("%lf  ",modelMatrix[4*i+j]);
		}
		printf("\n");
	}
	printf("========================================\n");
}

void keyboard (unsigned char key, int x, int y)
{

	switch (key)
	{
	case 27:
		exit(0);
		break;
	case 'a':
		moveForward(1);
		break;
	case 's':
		moveForward(2);
		break;
	case 'd':
		moveForward(3);
		break;
	}
}

int	main (int argc, char **argv)
{

	glutInit (&argc, argv);

	glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);

	glutInitWindowSize (300, 300);

	glutInitWindowPosition (100, 100);

	glutCreateWindow (argv[0]);

	init ();

	glutDisplayFunc (display);

	glutReshapeFunc (reshape);

	glutKeyboardFunc (keyboard);
     
	glutMainLoop ();
	return 0;
}
